package com.fql.research.common.shiro;

import java.util.List;
import java.util.Objects;

import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.fql.research.sys.domain.User;
import com.fql.research.sys.service.AuthService;
import com.fql.research.sys.service.RoleService;
import com.fql.research.sys.service.UserService;

/**
 * 自定义realm
 * @author fanql 2017年7月13日
 *
 */
public class ShiroAuthorizingRealm extends AuthorizingRealm {
	protected Logger logger = LoggerFactory.getLogger(super.getClass());
	@Autowired
	private UserService userService;
	@Autowired
	private RoleService roleService;
	@Autowired
	private AuthService authService;
	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		// 首先拿到用户名
		String currentUsername = (String)super.getAvailablePrincipal(principals);
		User user = new User();
		user.setUserName(currentUsername);
		List<String> roles = roleService.getByUserName(user);
		List<String> auths = authService.getByRole(roles);
		authorizationInfo.addRoles(roles);
		authorizationInfo.addStringPermissions(auths);
		this.logger.info("用户 [ {} ] 授权初始化成功......", currentUsername);
        this.logger.debug("用户 [ {} ] 角色列表为：{}", currentUsername, roles);
        this.logger.debug("用户 [ {} ] 权限列表为：{}", currentUsername, auths);
		return authorizationInfo;
	}

	/**
	 * 登录控制器
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 强转为usernamePasswordToken
		UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
		// 获取到页面上过来的用户名
		String username = usernamePasswordToken.getUsername();
		// 密码
		String password = String.valueOf(usernamePasswordToken.getPassword());
		if (username == null) {
            this.logger.warn("账号不能为空");
            throw new AccountException("账号不能为空");
        }
		User user = null;
		try {
			user = userService.getByUserName(username);
		} catch (Exception e) {
			this.logger.error("获取账号信息失败!",e);
		}
		if (null == user) {
			this.logger.warn("[ {} ]账号不存在!", username);
			throw new UnknownAccountException("账号不存在");
		}
		if (!Objects.equals(password, user.getUserPassword())) {
			this.logger.warn("[ {} ]密码不正确!", username);
			throw new IncorrectCredentialsException("密码不正确");
		}
		// 当前realm的名字
		String realmName = this.getName();
		Object principal = token.getPrincipal();
		return new SimpleAuthenticationInfo(principal, user.getUserPassword(),realmName);
	}

}
